%%%====================================================================
%%% File    : pipe_logger.erl
%%% Author  :  <vjache>
%%% Description: This is a simpliest pipe implementation. It may be 
%%%				 considered as a simple reference implementation of 
%%%				 a pipe callback module, and could be used for debug 
%%%				 purposes.
%%%
%%% Created : 24.03.2009
%%%====================================================================

-module(pipe_logger).

%%
%% Include files
%%
-include("../include/pipe.hrl").
-include("../include/pgt.hrl").
%%
%% Exported Functions
%%
-export([
		 new/0,
		 new/1,
		 new/2,
		 open/1,
		 push/2,
		 flush/1,
		 close/1,
		 create_file_name/1,
		 test/1,
		 test1/1,
		 test2/1
		 ]).

%%====================================================================
%% API Functions
%%====================================================================

new() ->
	new(pipe:terminator()).
new(NextPipe) when is_record(NextPipe, pipe) ->
	new(
	  fun(-1,Msg)->
			  io:format(">> "),
			  io:format(Msg),
			  io:format("~n");
	  	 (N,Msg)->
			  io:format(">>~p ~p~n",[N,Msg])
	  end, NextPipe);
new(Out) when is_function(Out,2) orelse is_list(Out) ->
	new(
	  Out, pipe:terminator()).
new(Out,NextPipe) when (is_function(Out,2) orelse is_list(Out)) andalso is_record(NextPipe, pipe) ->
	pipe:pipe_from_module(?MODULE, Out, NextPipe).

open({OutFun,NextPipe}) when is_function(OutFun,2) -> %%PipeState
    {OutFun,pipe:open(NextPipe),0};
open({Filename,NextPipe}) when is_list(Filename) -> %%PipeState
	{ok,Dev}=file:open(create_file_name(Filename), [write]),
    {Dev,pipe:open(NextPipe),0}.
push({OutFun,NextPipeState,N},Item) when is_function(OutFun,2) ->
    OutFun(N,Item),
	{OutFun,pipe:push(NextPipeState,Item),N+1};
push({Dev,NextPipeState,N},Item) ->
    io:format(Dev,"#~p(PG=~p)>> ~p~n",[N,?PG,Item]),
	{Dev,pipe:push(NextPipeState,Item),N+1}.
flush({OutFun,NextPipeState,N}) when is_function(OutFun,2) ->
	OutFun(-1,"Pipe flushed"),
	{OutFun,NextPipeState,N};
flush({Dev,NextPipeState,N}) ->
	io:format(Dev,"Pipe flushed~n",[]),
	{Dev,NextPipeState,N}.
close({OutFun,NextPipeState,_N}) when is_function(OutFun,2) ->
	OutFun(-1,"Pipe closed"),
	pipe:close(NextPipeState),
	ok;
close({Dev,NextPipeState,_N}) ->
	io:format(Dev,"Pipe closed",[]),
	ok=file:close(Dev),
	pipe:close(NextPipeState),
	ok.

create_file_name(BaseName) ->
	PidStr=lists:filter(fun(Char)->
						 (Char /=$>) and (Char /=$<)
				 end, pid_to_list(self())),
	lists:append([BaseName,"-",PidStr,atom_to_list(node()),".log"]).
%%====================================================================
%% Test Functions
%%====================================================================

test(L) when is_list(L) ->
	S=pipe:open(new()),
	{IterState,PipeState}=pipe:push_each(S, iter:from_list(L)),
	iter:close(IterState),
	pipe:close(PipeState).
test1(L) when is_list(L) ->
	S=pipe:open(new(pipe_console:new())),
	{IterState,PipeState}=pipe:push_each(S, iter:from_list(L)),
	iter:close(IterState),
	pipe:close(PipeState).
test2(L) when is_list(L) ->
	S=pipe:open(new("c:/pipe_logger.txt",pipe_console:new())),
	{IterState,PipeState}=pipe:push_each(S, iter:from_list(L)),
	iter:close(IterState),
	pipe:close(PipeState).


%%====================================================================
%% Local Functions
%%====================================================================

